#ifndef _BSP_H_
#define _BSP_H_

#include <stdint.h>
#include "gd32a508.h"

typedef struct
{
    uint64_t  timeCache;
    uint32_t  timeCostMs;
    uint32_t  timeCostUs;
    uint32_t  timerIndex;
} osTimeCost_T;

extern __IO uint32_t g_SysTickCount;


#define ENosTimeCost 1
#define SYSTICK_LOAD_REG             ( SysTick->LOAD)
#define SYSTICK_CURRENT_VALUE_REG    ( SysTick->VAL )
#define GetSysTick()          		 ( g_SysTickCount )
  /*
********************************************************************************
*                                osTaskGetTimeCost()
*                                   计时函数
* Description : 系统计时函数 ms
* Argument(s) : ms:单位ms、us(精度<5us)
* Return(s)   : 无
* Caller(s)   : Internal
* Note(s)     : 第一次调用初始化计时，之后每次调用得到两次时间差值.
              : 返回的index为0则为返回失败
              : 最多创建31个独立的计时
********************************************************************************
*/
__STATIC_INLINE void osTaskGetTimeCost(osTimeCost_T *pTimeCost)
{
# if ENosTimeCost
    static uint32_t allTimeCostCache[32] = {0};//allTimeCostCache[0]保留，如不为0则异常。
    static uint32_t currentTimeCostIndex = 0;

    uint32_t sysTickLoad = SYSTICK_LOAD_REG;
    uint32_t sysTickVal  = SYSTICK_CURRENT_VALUE_REG;

    uint32_t u32TickDiff = (sysTickLoad-sysTickVal);
    uint32_t u32NowUs = u32TickDiff/(SystemCoreClock/1000000);
    //考虑到在中断中使用，sysTick可能更新不及时，这里需要看情况给Ms补1
    uint32_t u32NowMs = GetSysTick();


    uint64_t u64Now   = u32NowMs*1000+u32NowUs;
    uint64_t u64TempTime = 0;

    //判断是否不允许使用
    if(allTimeCostCache[0]!= 0)
    {
        return;
    }

    //判断有无初始化
    if(currentTimeCostIndex == 0
            ||allTimeCostCache[pTimeCost->timerIndex] != (uint32_t)(pTimeCost)
            ||pTimeCost->timerIndex == 0)
    {
        currentTimeCostIndex++;
        //判断是否要生成新的计时器
        if(currentTimeCostIndex>=32)
        {
            currentTimeCostIndex--;
            pTimeCost->timerIndex = 0;
            return;
        }
        pTimeCost->timerIndex = currentTimeCostIndex;
        allTimeCostCache[pTimeCost->timerIndex] = (uint32_t)(pTimeCost);
        pTimeCost->timeCostUs = u32NowUs;
        pTimeCost->timeCostMs = u32NowMs;
    }
    else
    {
        //计时和缓存
        if(pTimeCost->timeCache <= u64Now)
        {
            u64TempTime = u64Now - pTimeCost->timeCache;
        }
        else
        {
            //不可能出现
            u64TempTime = 0xFFFFFFFFFFFFFFFF - pTimeCost->timeCache + u64Now;
        }
        pTimeCost->timeCostUs = (uint32_t)(u64TempTime%1000);
        pTimeCost->timeCostMs = (uint32_t)(u64TempTime/1000);
    }

    pTimeCost->timeCache = u64Now;
#endif
}

#endif